package com.mnsq.common.aop;

import com.mnsq.common.bean.annotation.UserInfoRequired;
import com.mnsq.common.bean.conf.ThreadLocalInfo;
import com.mnsq.common.bean.dto.LoginInfo;
import com.mnsq.common.bean.conf.ThreadLocalUserId;
import com.mnsq.common.bean.enums.ErrorCodeEnum;
import com.mnsq.common.service.RedisServer;
import lombok.extern.slf4j.Slf4j;
import matrix.module.common.bean.Result;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Administrator
 * @date 2019/4/6 0006
 */
@Aspect
@Slf4j
@Component
@EnableAspectJAutoProxy
public class UserInfoAspect {
    private static final String HEAD_KEY = "Authorization";

    @Autowired
    private RedisServer<String, LoginInfo> redisServer;

    @Around(value = "execution(* *.*(..)) && @annotation(userInfoRequired)")
    public Object loginInfoSet(ProceedingJoinPoint pjp, UserInfoRequired userInfoRequired) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String headKey = request.getHeader(HEAD_KEY);
        if (StringUtils.isBlank(headKey)) {
            if (userInfoRequired.required()) {
                return Result.fail("当前未登录，请登录后操作。").setResultCode(ErrorCodeEnum.NO_LOGIN.code);
            }
        } else {
            String token = headKey.substring(6);
            LoginInfo loginInfo = redisServer.get(token, LoginInfo.class);
            if (loginInfo == null) {
                if (userInfoRequired.required()) {
                    return Result.fail("当期登录已过期，请登录后操作。").setResultCode(ErrorCodeEnum.NO_LOGIN.code);
                }
            } else {
                ThreadLocalInfo.LOGIN_INFO.set(loginInfo);
                ThreadLocalUserId.CURRENT_USER_ID.set(loginInfo.getUserId());
            }
        }
        Object obj = pjp.proceed();
        ThreadLocalInfo.LOGIN_INFO.remove();
        ThreadLocalUserId.CURRENT_USER_ID.remove();
        return obj;
    }
}
